package com.mastercard.labs
import org.apache.shiro.SecurityUtils
import org.apache.shiro.authc.AuthenticationException
import org.apache.shiro.authc.UsernamePasswordToken

class ProfileController {
	def userService
	def cardService
	def dealService
	def shiroSecurityService
	def card
    def index() {redirect (action:"show") }
	def show() {
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		def cards = cardService.getCards(userInstance)
		def budgets = Budget.findAllByUserAndDeletedAndBudget(userInstance, false, true)
		def targets = Budget.findAllByUserAndDeletedAndBudget(userInstance, false, false)
		def userCategories = UserCategory.findAllByUserAndDeleted (userInstance, false)
		def allCategories = Category.findAll()
		ArrayList <UserCategoryBO> userCategoryList = new ArrayList<UserCategoryBO>()
		for (category in allCategories){
			UserCategoryBO bo = new UserCategoryBO()
			bo.categoryId = category.id
			bo.categoryName = category.name
			for(userCategory in userCategories){
				if(userCategory.category.id == category.id){
					bo.selected = true
					bo.userCategoryId = userCategory.id;
				}
			}
			userCategoryList.add(bo)
		}
		session.setAttribute("user_categories", userCategoryList)		
		
		[userInstance: userInstance, cards:cards, budgets:budgets, targets:targets, categories:userCategoryList, deals: dealService.getDeals(userInstance)]
	}
	def editProfile() {
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		[userInstance: userInstance, deals: dealService.getDeals(userInstance)]
	}
	def updateProfile(){
		def userInstance = User.get(SecurityUtils.subject.session.getAttribute("current_user").id)
		userInstance.properties = params
		if (!userInstance.save(flush:true)) {
			log.info "validation failed"
			render (view: 'editProfile', model: [userInstance: userInstance])
			return
		}
		userInstance = User.get(SecurityUtils.subject.session.getAttribute("current_user").id)
		userInstance.roles
		SecurityUtils.subject.session.setAttribute("current_user", userInstance)
		redirect(action: "show")
	}
	
	def changePassword() {
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		if (!userInstance) {
			flash.message = message(code: 'default.not.found.message', args: "user ", ${SecurityUtils.subject.principal})
			return
		}
		[userInstance: userInstance, deals: dealService.getDeals(userInstance)]
	}
	def updatePassword(){
		def userInstance = userService.getUserById(SecurityUtils.subject.session.getAttribute("current_user").id)
		if (!userInstance) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.name])
			redirect(action: "search", model: [searchCondition: params.searchCondition])
			return
		}
		if (params.version) {
			def version = params.version.toLong()
			if (userInstance.version > version) {
				userInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
					[message(code: 'user.label', default: 'User')] as Object[],
					"Another user has updated this User while you were editing")
				render(view: "show", model: [userInstance: userInstance])
				return
			}
		}
		log.info "${params.oldPassword} ${params.newPassword} ${params.newPassword2}"
		log.info (shiroSecurityService.encodePassword(params.oldPassword))
		log.info "${userInstance.passwordHash}"
		
		if(userInstance.passwordHash != shiroSecurityService.encodePassword(params.oldPassword)){
			flash.message = 'wrong password'
			log.info "wrong password"
			redirect(action: "changePassword")
			return
		}
		if(params.newPassword != params.newPassword2){
			flash.message = 'new password not match'
			log.info "new password not match"
			redirect(action: "changePassword")
			return
		}
		else if(params.newPassword.length() < 6) {
			flash.message = "password too short, please choose password longer than 5 charactors"
			redirect(action: "changePassword")
			return
		}
		userInstance.passwordHash = shiroSecurityService.encodePassword(params.newPassword)
		userService.saveUser(userInstance)
		SecurityUtils.subject.session.setAttribute("current_user", userInstance)
		userInstance.roles
		//render(view: "show", model: [userInstance: userInstance])
		redirect(action: "show")
	}
	def editCard() {
		log.info "editCard ${params.id}"
		def userInstance = userService.getUserById(SecurityUtils.subject.session.getAttribute("current_user").id)
		def cardInstance =Card.read(params.id)
		def banks = Bank.getAll()
		render (view: 'card', model: [cardInstance: cardInstance, banks:banks, deals: dealService.getDeals(userInstance)])
	}
	
	def saveCard(){
		log.info "saveCard ${params.id}"
		def cardInstance = null
		if(params.id){
			cardInstance =Card.get(params.id)
		}else{
			cardInstance = new Card()
		}
		def bankid = params.bankid
		def bank = Bank.get(bankid)
		cardInstance.bank = bank
		cardInstance.properties = params
		if (!cardInstance.save(flush:true)) {
			log.info "validation failed"
			render (view: 'card', model: [cardInstance: cardInstance, banks: Bank.getAll()])
			return
		}
		if(!params.id){
			def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
			new UserCard(user:userInstance, card:cardInstance).save(flush:true)
		}
		redirect(action: "show")
	}
	
	def removeCard() {
		log.info "removeCard ${params.id}"
		def cardInstance = Card.get(params.id)
		cardInstance.deleted = true
		cardInstance.save(flush:true, failOnError: true);
		redirect(action: "show")
	}
	def addCard(){
		def userInstance = userService.getUserById(SecurityUtils.subject.session.getAttribute("current_user").id)
		render (view: 'card', model: [banks:Bank.getAll(), deals: dealService.getDeals(userInstance)])
	}
//	def saveCard(){
//		log.info "saveCard"
//		def cardInstance = new Card()
//		def bankid = params.bankid
////		def newParams = params.findAll { it.key != bankid }
//		def bank = Bank.get(bankid)
//		cardInstance.properties = params
//		cardInstance.bank = bank
//		if (!cardInstance.save(flush:true) ){
//			log.info "validation failed"
//			render(view: 'addCard', model: [card: cardInstance, banks:Bank.getAll()])
//			return
//		}
//		def userInstance = userService.getUserById(SecurityUtils.subject.session.getAttribute("current_user").id)
//		new UserCard(user:userInstance, card:cardInstance).save(flush:true)
//		redirect(action: "show")
//	}
	def addBudget(){
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		def cards = cardService.getCards(userInstance)
		render (view: 'budget', model: [cards: cards, deals: dealService.getDeals(userInstance)])
	}
	
	def saveBudget(){
		log.info "saveBudget ${params.id}"
		def budgetInstance = null
		if(params.id){
			budgetInstance = Budget.get(params.id)
		}else{
			budgetInstance = new Budget()
		}
		def card = null
		if(params.type != Budget.Type.ALL){
			def cardId = params.cardId
			card = Card.get(cardId)
		}
		budgetInstance.properties = params
		//budgetInstance.billDate = params.billDate
		budgetInstance.card = card
		budgetInstance.user = SecurityUtils.subject.session.getAttribute("current_user")
		log.info "billDate = ${budgetInstance.billDate} ${params.billDate}"
		if (!budgetInstance.save(flush:true)) {
			log.info "validation failed"
			render (view: 'budget', model: [cards: cardService.getCards(budgetInstance.user), budgetInstance: budgetInstance])
			return
		}
		redirect(action: "show")
	}
	def editBudget() {
		log.info "editBudget ${params.id}"
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		def budgetInstance =Budget.read(params.id)
		def cards = cardService.getCards(userInstance)
		render (view: 'budget', model:[budgetInstance: budgetInstance, cards:cards, deals: dealService.getDeals(userInstance)])
	}
	
	def updateBudget(){
		log.info "updateBudget ${params.id}"
		def budgetInstance =Budget.get(params.id)
		def cardId = params.cardId
//		def newParams = params.findAll { it.key != bankid }
		def card = Card.get(cardId)
		budgetInstance.properties = params
		budgetInstance.card = card
		if (!budgetInstance.save(flush:true)) {
			log.info "validation failed"
			render (view: 'updateBudget', model: [cards: cardService.getCards(budgetInstance.user), budgetInstance: budgetInstance])
			return
		}
		redirect(action: "show")
	}
	def removeBudget(){
		log.info "removeCard ${params.id}"
		def budgetInstance = Budget.get(params.id)
		budgetInstance.deleted = true
		budgetInstance.save(flush:true, failOnError: true);
		redirect(action: "show")
	}
	
	
	def addTarget(){
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		def cards = cardService.getCards(userInstance)
		render (view: 'target', model: [cards: cards, deals: dealService.getDeals(userInstance)])
	}
	
	def saveTarget(){
		def targetInstance = null
		if(params.id){
			targetInstance =Target.get(params.id)
		}else{
			targetInstance = new Target()
		}
		def card = new Card()
		log.info "type = ${params.type}"
		if (params.type != Target.Type.ALL){
		log.info "type = ${params.type}"
			def cardId = params.cardId
			card = Card.get(cardId)	
		}
		targetInstance.properties = params
		targetInstance.card = card
		targetInstance.user = SecurityUtils.subject.session.getAttribute("current_user")
		if (!targetInstance.save(flush:true)) {
			log.info "validation failed"
			render (view: 'target', model: [cards: cardService.getCards(targetInstance.user), targetInstance: targetInstance])
			return
			
		}		
		redirect(action: "show")
	}
	def editTarget() {
		log.info "editTarget ${params.id}"
		def userInstance = SecurityUtils.subject.session.getAttribute("current_user")
		def targetInstance =Target.read(params.id)
		def cards = cardService.getCards(userInstance)
		render (view: 'target', model: [targetInstance: targetInstance, cards:cards, deals: dealService.getDeals(userInstance)])
	}
	
	def updateTarget(){
		log.info "updateTarget ${params.id}"
		def targetInstance =Target.get(params.id)
		def cardId = params.cardId
//		def newParams = params.findAll { it.key != bankid }
		def card = Card.get(cardId)
		targetInstance.properties = params
		targetInstance.card = card
		if (!targetInstance.save(flush:true)) {
			log.info "validation failed"
			render (view: 'updateTarget', model: [cards: cardService.getCards(targetInstance.user), targetInstance: targetInstance])
			return
		}
		redirect(action: "show")
	}
	def removeTarget(){
		log.info "removeCard ${params.id}"
		def targetInstance = Target.get(params.id)
		targetInstance.deleted = true
		targetInstance.save(flush:true, failOnError: true);
		redirect(action: "show")
	}
	
	def updateUserCategory () {
		log.info params.get("category[0]")
		log.info params
		def userCategories = session.getAttribute("user_categories")
		int i = 0;
		while (true){
			def selection = params.get("category["+ i++ + "]")
			log.info "selection ${i - 1} : ${selection}"
			if(selection == null){
				break
			}
			userCategories.each () {
				if (it.categoryId == selection.categoryId.toLong()){
					log.info it.selected
					log.info selection.selected
					if(it.selected == true && selection.selected == null){
						log.info "delete ${selection.categoryId}"
						def uc = UserCategory.findByCategory(Category.read(it.categoryId))
						uc.delete()
					}else if(it.selected == false && selection.selected == 'on'){
					log.info "create ${selection.categoryId}"
						UserCategory uc = new UserCategory()
						uc.user = SecurityUtils.subject.session.getAttribute("current_user")
						uc.category = Category.read(selection.categoryId)
						uc.save()
					}else{
						log.info "${selection.categoryId} unchanged"
					}
				}
			}
		}
		redirect(action: "show")
	}
}
